package org.tio.showcase.websocket.server;

import java.util.Objects;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.tio.core.Tio;
import org.tio.core.ChannelContext;
import org.tio.http.common.HttpRequest;
import org.tio.http.common.HttpResponse;
import org.tio.utils.SystemTimer;
import org.tio.websocket.common.WsRequest;
import org.tio.websocket.common.WsResponse;
import org.tio.websocket.common.WsSessionContext;
import org.tio.websocket.server.handler.IWsMsgHandler;

import com.googlecode.protobuf.format.JsonFormat;
import com.im.common.packets.ChatReqBody;
import com.im.common.packets.ChatRespBody;
import com.im.common.packets.ChatType;

/**
 * @author tanyaowu 2017年6月28日 下午5:32:38
 */
public class ShowcaseWsMsgHandler implements IWsMsgHandler {
	private static Logger log = LoggerFactory.getLogger(ShowcaseWsMsgHandler.class);

	public static ShowcaseWsMsgHandler me = new ShowcaseWsMsgHandler();
	
	public static JsonFormat jsonFormat = new JsonFormat();

	private ShowcaseWsMsgHandler() {

	}

	/**
	 * 握手时走这个方法，业务可以在这里获取cookie，request参数等
	 */
	@Override
	public HttpResponse handshake(HttpRequest request, HttpResponse httpResponse, ChannelContext channelContext)
			throws Exception {
		String clientip = request.getClientIp();
		log.info("收到来自{}的ws握手包\r\n{}", clientip, request.toString());
		return httpResponse;
	}

	/**
	 * @param httpRequest
	 * @param httpResponse
	 * @param channelContext
	 * @throws Exception
	 * @author tanyaowu
	 */
	@Override
	public void onAfterHandshaked(HttpRequest httpRequest, HttpResponse httpResponse, ChannelContext channelContext)
			throws Exception {
		
		String group = httpRequest.getHeader("group");
		if (StringUtils.isBlank(group)) {
			group = httpRequest.getParam("group");
			if (StringUtils.isBlank(group)) {
				group = Const.GROUP_ID;
			}
		}
		// 绑定到群组，后面会有群发
		Tio.bindGroup(channelContext, group);
		int count = Tio.getAllChannelContexts(channelContext.getGroupContext()).getObj().size();

		String msg = channelContext.getClientNode().toString() + " 进来了，现在共有【" + count + "】人在线";

		log.info("\r\nws握手后连接数:{}", msg);

		/*
		 * //用tio-websocket，服务器发送到客户端的Packet都是WsResponse WsResponse wsResponse =
		 * WsResponse.fromText(msg, ShowcaseServerConfig.CHARSET); //群发
		 * Tio.sendToGroup(channelContext.getGroupContext(), Const.GROUP_ID,
		 * wsResponse);
		 */
	}

	/**
	 * 字节消息（binaryType = arraybuffer）过来后会走这个方法
	 */
	@Override
	public Object onBytes(WsRequest wsRequest, byte[] bytes, ChannelContext channelContext) throws Exception {
		WsSessionContext wsSessionContext = (WsSessionContext) channelContext.getAttribute();
		HttpRequest httpRequest = wsSessionContext.getHandshakeRequestPacket();//获取websocket握手包
		String group = httpRequest.getHeader("group");
		String name = httpRequest.getHeader("name");
		if(StringUtils.isBlank(group)) {
			group = httpRequest.getParam("group");
			if(StringUtils.isBlank(group)) {
				group = Const.GROUP_ID;
			}
		}
		if(StringUtils.isBlank(name)) {
			name = httpRequest.getParam("name");
			if(StringUtils.isBlank(name)) {
				name = "匿名";
			}
		}
		log.info("onBytes收到ws消息:{}", new String(bytes,ShowcaseServerConfig.CHARSET));
		
		
		ChatReqBody chatReqBody = ChatReqBody.parseFrom(bytes);
		String asJson = jsonFormat.printToString(chatReqBody);
		log.info("onBytes to Json 收到ws消息:{}", asJson);
		String text = chatReqBody.getText();
		
		if(StringUtils.isNotEmpty(text) && text.equals("exit")) {
			//移除群组
			Tio.remove(channelContext, "user exit");
			int count = Tio.getAllChannelContexts(channelContext.getGroupContext()).getObj().size();
			log.info("[{}] 退出群组后剩余人数:[{}]",name, count);
			return null;
		}
		
		ChatRespBody.Builder builder = ChatRespBody.newBuilder();
		builder.setType(ChatType.CHAT_TYPE_PUBLIC);
		builder.setText(text);
		builder.setFromNick(name);
		builder.setGroup(chatReqBody.getGroup());
		builder.setTime(SystemTimer.currentTimeMillis());
		ChatRespBody chatRespBody = builder.build();
		byte[] bodybyte = chatRespBody.toByteArray();
		
		
		//用tio-websocket，服务器发送到客户端的Packet都是WsResponse
		WsResponse wsResponse = WsResponse.fromBytes(bodybyte);
		//群发
		Tio.sendToGroup(channelContext.getGroupContext(), group, wsResponse);
		return null;
	}

	/**
	 * 当客户端发close flag时，会走这个方法
	 */
	@Override
	public Object onClose(WsRequest wsRequest, byte[] bytes, ChannelContext channelContext) throws Exception {
		Tio.remove(channelContext, "receive close flag");
		return null;
	}

	/*
	 * 字符消息（binaryType = blob）过来后会走这个方法
	 */
	@Override
	public Object onText(WsRequest wsRequest, String text, ChannelContext channelContext) throws Exception {
		WsSessionContext wsSessionContext = (WsSessionContext) channelContext.getAttribute();
		HttpRequest httpRequest = wsSessionContext.getHandshakeRequestPacket();// 获取websocket握手包
		String group = httpRequest.getHeader("group");
		String name = httpRequest.getHeader("name");
		if(StringUtils.isBlank(group)) {
			group = httpRequest.getParam("group");
			if(StringUtils.isBlank(group)) {
				group = Const.GROUP_ID;
			}
		}
		if(StringUtils.isBlank(name)) {
			name = httpRequest.getParam("name");
			if(StringUtils.isBlank(name)) {
				name = "匿名";
			}
		}
		if (log.isDebugEnabled()) {
			log.debug("握手包:{}", httpRequest);
		}

		log.info("收到ws消息:{}", text);

		if (Objects.equals("心跳内容", text)) {
			return null;
		}

//		String msg = channelContext.getClientNode().toString() + " 说：" + text;
		String msg = "昵称:"+ name + " 说：" + text;
		// 用tio-websocket，服务器发送到客户端的Packet都是WsResponse
		WsResponse wsResponse = WsResponse.fromText(msg, ShowcaseServerConfig.CHARSET);
		// 群发
		Tio.sendToGroup(channelContext.getGroupContext(), group, wsResponse);

		// 返回值是要发送给客户端的内容，一般都是返回null
		return null;
	}

}
